﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Nomad.WebSync.Extensions {
    internal static class SecurityExtension {
        private static byte[] KEY = new byte[] { 84, 61, 145, 163, 190, 87, 28, 154, 151, 194, 111, 105, 170, 135, 10, 210, 9, 215, 248, 165, 223, 141, 234, 55, 121, 216, 140, 58, 121, 170, 151, 113 };
        private static byte[] IV = new byte[] { 204, 125, 207, 206, 70, 190, 79, 15, 42, 181, 240, 40, 47, 193, 132, 38 };

        /// <summary>
        /// Encrypt a string with a password key based
        /// </summary>
        /// <param name="value">String from encrypt</param>
        /// <returns>Encrypt string</returns>
        public static string Encrypt(this string value) {
            if (String.IsNullOrEmpty(value))
                return value;

            var bytes = value.GetBytes();
            var result = bytes.Encrypt();
            return Convert.ToBase64String(result);
        }
        public static byte[] Encrypt(this byte[] value) {
            var memory = new MemoryStream();
            var engine = Rijndael.Create();
            using (var cryptStream = new CryptoStream(memory, engine.CreateEncryptor(KEY, IV), CryptoStreamMode.Write)) {
                cryptStream.Write(value, 0, value.Length);
                cryptStream.Close();
            }
            return memory.ToArray();
        }

        /// <summary>
        /// Dencrypt a string with a password key based
        /// </summary>
        /// <param name="value">String from dencrypt</param>
        /// <returns>Dencrypt string</returns>
        public static string Decrypt(this string value) {
            if (String.IsNullOrEmpty(value))
                return value;

            var bytes = Convert.FromBase64String(value);
            var result = bytes.Decrypt();
            return result.GetString();
        }
        public static byte[] Decrypt(this byte[] value) {
            var memory = new MemoryStream();
            var engine = Rijndael.Create();
            using (var cryptStream = new CryptoStream(memory, engine.CreateDecryptor(KEY, IV), CryptoStreamMode.Write)) {
                cryptStream.Write(value, 0, value.Length);
                cryptStream.Close();
            }
            return memory.ToArray();
        }

        /// <summary>
        /// Compute unique hash code from a string
        /// </summary>
        /// <param name="value">String to compute hash</param>
        /// <returns>Hash from string</returns>
        public static string Hash(this string value) {
            var result = SHA1.Create().ComputeHash(value.GetBytes());
            return Convert.ToBase64String(result);
        }

        public static byte[] GetBytes(this string value) {
            return Encoding.ASCII.GetBytes(value);
        }
        public static string GetString(this byte[] value) {
            var result = String.Empty;
            var chars = Encoding.ASCII.GetChars(value);
            foreach (var c in chars) {
                result += c;
            }
            return result;
        }
    }
}
